Passed
Push — main ( 792997...b64a3d )
by Andrii
02:52
created

readme.spec.tsx ➔ DialogButton   A

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
1
import React from "react"
2
import expectRender from "../expect-to-same-render"
3
import classNaming, { classBeming } from "../src"
4
import type {ClassHash, ClassNamesProperty} from "../src"
5
// import css_module from "./button.module.css"
6
const css_module = {button: "BTN"}
7
8
it("Basic usage", () => {
9
  type Props = {
10
    isValid: boolean
11
    readOnly: boolean
12
  }
13
14
  // isValid = false, readOnly = false
15
  function FormButtons({isValid, readOnly}: Props) {
16
    const cssClasses = classNaming()
17
    const buttonClass = cssClasses({"button": true}) // "button"
18
    
19
    return <>
20
      <button {
21
        ...buttonClass // className="button" 
22
      }>Close</button>
23
      <button type="reset" {
24
        ...buttonClass({"button--disabled": readOnly}) // className="button"
25
      }>Reset</button> 
26
                        {/* className="button_submit button button--disabled" */}
27
      <button type="submit" className={`button_submit ${
28
        buttonClass({"button--disabled": readOnly || !isValid}) // "button button--disabled"
29
      }`}>Submit</button> 
30
    </>
31
  }  
32
33
  expectRender(
34
    <FormButtons isValid={false} readOnly={false} />
35
  ).toSame(<>
36
    <button className="button">Close</button>
37
    <button type="reset" className="button">Reset</button>
38
    <button type="submit" className="button_submit button button--disabled">Submit</button>
39
  </>)
40
})
41
42
it("Strict type", () => {
43
  type Props = {readOnly?: boolean}
44
  const {readOnly} = {} as Props
45
  const cssClasses = classNaming()
46
  const disabling = cssClasses({
47
    //@ts-expect-error Type 'boolean | undefined' is not assignable to type 'boolean'
48
    "button--disabled": readOnly
49
  })
50
51
  expect({...disabling}).toStrictEqual({className: "button--disabled"})
52
})
53
54
it("Single source of truth", () => {
55
  const cssClasses = classNaming()
56
  const isValidClass = cssClasses({"button--disabled": /* !isValid */ false })
57
  // ... more code
58
  const buttonClass = isValidClass({button: true})
59
  // ... more code
60
  const disablingClass = buttonClass({
61
    //@ts-expect-error Type 'boolean' is not assignable to type 'never'
62
    "button--disabled": true
63
  })
64
  
65
  expect({...disablingClass}).toStrictEqual({
66
    className: "button button--disabled"
67
  })
68
})
69
70
it("Declare own component's CSS classes", () => {
71
  type MyClassNames = ClassNamesProperty<{
72
    button: ClassHash
73
    button_submit: ClassHash
74
    "button--disabled": ClassHash
75
  }>
76
  type Props = {
77
    isValid: boolean
78
    readOnly: boolean
79
  }
80
81
  // isValid = false, readOnly = false
82
  function FormButtons({isValid, readOnly}: Props) {
83
    const cssClasses = classNaming<MyClassNames>()
84
    const buttonClass = cssClasses({button: true})
85
    
86
    return <>
87
      <button {
88
        ...buttonClass // className="button" 
89
      }>Close</button>
90
      <button type="reset" {
91
        ...buttonClass({
92
        "button--disabled": readOnly
93
      }) // className="button"
94
      }>Reset</button> 
95
      <button type="submit" {
96
        ...buttonClass({
97
          "button_submit": true,
98
          "button--disabled": readOnly || !isValid
99
        }) // className="button button_submit button--disabled"
100
      }>Submit</button> 
101
    </>
102
  }  
103
104
  expectRender(
105
    <FormButtons isValid={false} readOnly={false} />
106
  ).toSame(<>
107
    <button className="button">Close</button>
108
    <button type="reset" className="button">Reset</button>
109
    <button type="submit" className="button button_submit button--disabled">Submit</button>
110
  </>)
111
})
112
113
it("Using ClassHash", () => {
114
  // CSS-module
115
  const { button } = css_module
116
117
  // Module simulation
118
  type CssModuleSimulation = { button_submit: ClassHash }
119
  const { button_submit } = {} as CssModuleSimulation
120
  
121
  type MyClassNames = ClassNamesProperty<
122
    typeof css_module &
123
    CssModuleSimulation &
124
    {
125
      "button--disabled": ClassHash
126
    }
127
  >
128
  type Props = {
129
    isValid: boolean
130
    readOnly: boolean
131
  }
132
133
  // isValid = false, readOnly = false
134
  function FormButtons({isValid, readOnly}: Props) {
135
    const cssClasses = classNaming<MyClassNames>()
136
    const buttonClass = cssClasses({ button })
137
    
138
    return <>
139
      <button {
140
        ...buttonClass // className="BTN" 
141
      }>Close</button>
142
      <button type="reset" {
143
        ...buttonClass({
144
          "button--disabled": readOnly
145
      }) // className="BTN"
146
      }>Reset</button> 
147
      <button type="submit" {...buttonClass({
148
        button_submit,
149
        "button--disabled": readOnly || !isValid
150
      }) // "BTN button_submit button--disabled"
151
      }>Submit</button> 
152
    </>
153
  }  
154
155
  expectRender(
156
    <FormButtons isValid={false} readOnly={false} />
157
  ).toSame(<>
158
    <button className="BTN">Close</button>
159
    <button type="reset" className="BTN">Reset</button>
160
    <button type="submit" className="BTN button_submit button--disabled">Submit</button>
161
  </>)
162
})
163
164
describe("bem leaf", () => {
165
  type Props = ClassNamesProperty<MaterialClasses>
166
  & { focused?: boolean }
167
168
  function DialogButton({focused}: Props) {
169
    const bem = classBeming<Props>()
170
  
171
    return <button {...bem({
172
      dialog__button: true,
173
      button: {type: "raised"},
174
      ripple: focused && "background-focused"
175
    })}/>
176
  }
177
178
  
179
  const props = {focused: true} as Props
180
181
  expectRender(
182
    <DialogButton {...props}/>
183
  ).toSame(
184
    <button className="dialog__button button button--type--raised ripple ripple--background-focused" />
185
  )
186
})
187
188
type MaterialClasses = {
189
  "material-icons": ClassHash
190
  ripple: ClassHash
191
  "ripple--bounded": ClassHash
192
  "ripple--unbounded": ClassHash
193
  "ripple--background-focused": ClassHash
194
  "ripple--foreground-activation": ClassHash
195
  "ripple--foreground-deactivation": ClassHash
196
  button: ClassHash
197
  "button--type--raised": ClassHash
198
  "button--type--outlined": ClassHash
199
  button__label: ClassHash
200
  button__ripple: ClassHash
201
  button__icon: ClassHash
202
  dialog: ClassHash
203
  dialog__button: ClassHash
204
}
205